/*
 * Copyright 2011 The Rusted Roof, LLC.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package org.proteusframework.sample.theme.swing;

import org.proteusframework.core.api.IProteusConstants;
import org.proteusframework.core.api.model.INamespace;
import org.proteusframework.core.base.DisplayableName;
import org.proteusframework.core.base.Namespace;
import org.proteusframework.core.util.Assert;
import org.proteusframework.platformservice.AbstractServicePlugin;
import org.proteusframework.platformservice.IExtendedPlatformDelegate;
import org.proteusframework.platformservice.theme.IThemeService;
import org.proteusframework.platformservice.theme.menu.IMenuBlock;
import org.proteusframework.platformservice.theme.menu.IMenuBlockItem;
import org.proteusframework.platformservice.theme.menu.MenuEvent;
import org.proteusframework.platformservice.theme.panel.IContentBlock;
import org.proteusframework.platformservice.theme.panel.IDialog;
import org.proteusframework.platformservice.theme.panel.IPanelBlock;
import org.proteusframework.platformservice.theme.panel.IProgressDialog;
import org.proteusframework.platformservice.theme.toolbar.IToolbar;
import org.proteusframework.platformservice.theme.toolbar.IToolbarItem;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Logger;

public class SwingTheme extends AbstractServicePlugin implements IThemeService
{
    private static final Logger logger = Logger.getLogger(SwingTheme.class.getCanonicalName());

    public static final INamespace DN = new Namespace(IProteusConstants.NAMESPACE, "Theme1");

    private JFrame frame;
    private JMenuBar menuBar;

    public SwingTheme()
    {
        super(new DisplayableName(DN), SwingTheme.class);
    }

    @Override
    public void stop()
    {
    }


    @Override
    public void start()
    {

    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T getFrame(Class<?> expectedFrameType) throws IllegalArgumentException
    {
        T targetFrame = null;

        if (null == frame)
        {
            throw new IllegalStateException("The frame isn't initialized and is unavailable at this time");
        }

        Assert.parameterNotNull(expectedFrameType, "Parameter 'expectedFrameType' must not be null");

        if (expectedFrameType.isAssignableFrom(frame.getClass()))
        {
            targetFrame = (T) expectedFrameType.cast(frame);
        } else
        {
            throw new IllegalArgumentException("The frame is not assignable from " + expectedFrameType.getCanonicalName());
        }

        return targetFrame;
    }

    @Override
    public void createFrame()
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                //
                // Create a new JFrame
                //
                try
                {
                    UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                } catch (Exception e)
                {
                    logger.warning(e.getMessage());
                }

                menuBar = new JMenuBar();

                frame = new JFrame("Sample Theme One");
                frame.setSize(640, 480);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setJMenuBar(menuBar);
                frame.setVisible(true);
            }
        });

    }

    @Override
    public void createContentBlock(IContentBlock contentBlock)
    {
        frame.getContentPane().add((Component) contentBlock.getComponent(), BorderLayout.CENTER);
    }

    @Override
    public void showDialog(IDialog dialog)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void createProgressDialog(IProgressDialog dialog, int minimumValue, int maximumValue)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void incrementProgress(INamespace progressNamespace)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void setProgressMessage(INamespace progressNamespace, String message)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void createMenuBlock(final IMenuBlock menuBlock)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                String label = menuBlock.getMetadata().getProperty(IMenuBlock.KEY_LABEL);

                JMenu menu = new JMenu(label);
                menuBar.add(menu);

                for (final IMenuBlockItem item : menuBlock.getItems())
                {
                    JMenuItem menuItem = new JMenuItem(item.getMetadata().getProperty(IMenuBlock.KEY_LABEL));

                    menuItem.addActionListener(new ActionListener()
                    {
                        @Override
                        public void actionPerformed(ActionEvent actionEvent)
                        {
                            item.fireEvent(new MenuEvent(item, actionEvent));
                        }
                    });

                    menu.add(menuItem);
                }

                frame.validate();
            }
        });
    }

    @Override
    public void createMenuBlock(final IMenuBlock menuBlock, final IMenuBlockItem... menuBlockItem)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                String label = menuBlock.getMetadata().getProperty(IMenuBlock.KEY_LABEL);

                JMenu menu = new JMenu(label);
                menuBar.add(menu);

                for (final IMenuBlockItem item : menuBlockItem)
                {
                    JMenuItem menuItem = new JMenuItem(item.getMetadata().getProperty(IMenuBlock.KEY_LABEL));

                    menuItem.addActionListener(new ActionListener()
                    {
                        @Override
                        public void actionPerformed(ActionEvent actionEvent)
                        {
                            item.fireEvent(new MenuEvent(item, actionEvent));
                        }
                    });

                    menu.add(menuItem);
                }

                frame.validate();
            }
        });
    }

    @Override
    public void createPanelBlock(IPanelBlock panelBlock)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void createToolbar(IToolbar toolBar)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void createToolbar(IToolbar toolBar, IToolbarItem... toolBarItem)
    {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void showErrorMessage(String message)
    {
        IExtendedPlatformDelegate extDelegate = delegate.adapt(IExtendedPlatformDelegate.class);
        String title = extDelegate.getAppConfigService().getAppName();
        JOptionPane.showMessageDialog(frame, message, title, JOptionPane.ERROR_MESSAGE);
    }

    @Override
    public int showConfirmDialog(String message, int optionType, int messageType)
    {
        IExtendedPlatformDelegate extDelegate = delegate.adapt(IExtendedPlatformDelegate.class);
        String title = extDelegate.getAppConfigService().getAppName();
        return JOptionPane.showConfirmDialog(frame, message, title, optionType, messageType);
    }

    @Override
    public void showStatusMessage(String message)
    {
        IExtendedPlatformDelegate extDelegate = delegate.adapt(IExtendedPlatformDelegate.class);
        String title = extDelegate.getAppConfigService().getAppName();
        JOptionPane.showMessageDialog(frame, message, title, JOptionPane.INFORMATION_MESSAGE);
    }
}
